home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
misc
/
amag
/
sh9302a.lha
/
Patchen (S.53)
/
VPatch
/
VPatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-23
|
7KB
|
272 lines
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <exec/exec.h>
#include <intuition/intuition.h>
#include <proto/dos.h>
#include <proto/exec.h>
extern BPTR __asm newopen(register __d1 char *,register __d2 long);
extern BPTR __asm newlock(register __d1 char *,register __d2 long);
void main(int,char **);
extern struct DosLibrary *DOSBase;
extern struct ExecBase *SysBase;
APTR oldOpen,oldLock;
/* Struktur, um Verwaltungsdaten für Extensionen aufzunehmen */
typedef struct
{
char extension[80];
long length;
} VINFO;
VINFO *info;
long anzahl;
void main(int argc,char **argv)
{
struct IntuiMessage send,*receive;
struct MsgPort *port;
BPTR file;
char buffer[80];
int i=0;
VINFO *inf;
/* Ist ein Message-Port mit Namen "VPort" vorhanden ? Ja, dann Message
mit der Klasse 0xffffffff absenden
*/
if (port=FindPort("VPort"))
{
send.Class=0xffffffff;
PutMsg(port,(struct Message*)&send);
FPuts(Output(),"DOS-Open() u. DOS-Lock() Patch aufgehoben\n");
return;
}
else
{
if (argc!=2)
{
FPuts(Output(),"FORMAT : vpatch <Parameterdatei>\n");
return;
}
/* angegebene Parameterdatei einlesen */
if (file=Open(argv[1],MODE_OLDFILE))
{
while (FGets(file,buffer,79))
{
/* Keine Leerzeile */
if (strcmp(buffer,"\n"))
{
/* "realloc()" von Hand ... */
inf=info;
if (info=AllocVec((i+1)*sizeof(VINFO),MEMF_CLEAR|MEMF_PUBLIC))
{
CopyMem(inf,info,i*sizeof(VINFO));
FreeVec(inf);
/* ... und dann Daten einkopieren */
strcpy((*(info+i)).extension,buffer);
(*(info+i)).length=strlen(buffer)-1;
(*(info+i)).extension[(*(info+i)).length]='\0';
i++;
}
else
{
FreeVec(info);
FPuts(Output(),"Kein freier Speicher für Extensionsliste\n");
Close(file);
return;
}
}
}
anzahl=i;
/* Message-Port einrichten, Vektoren verbiegen und auf spezielle
Message warten, dann Vektoren wiederherstellen und Programm
beenden.
*/
if (port=CreateMsgPort())
{
port->mp_Node.ln_Name="VPort";
AddPort(port);
oldOpen=SetFunction((struct Library*)DOSBase,-30,newopen);
oldLock=SetFunction((struct Library*)DOSBase,-84,newlock);
FPuts(Output(),"DOS-Open() u. DOS-Lock() gepatcht\n");
Close(file);
do
{
receive=(struct IntuiMessage*)WaitPort(port);
} while (receive->Class!=0xffffffff);
FreeVec(info);
RemPort(port);
DeleteMsgPort(port);
SetFunction((struct Library*)DOSBase,-30,oldOpen);
SetFunction((struct Library*)DOSBase,-84,oldLock);
}
}
else if (!file)
FPuts(Output(),"Parameterdatei nicht vorhanden\n");
}
return;
}
extern BPTR __asm newopen(register __d1 char *name,register __d2 long mode)
{
char newname[256],hilfe[256],*p;
BPTR fh;
short x=0,len,kenn=-1,pos=0,in=0;
/* Zugriff auf globale Daten, Libraryadressen etc. */
geta4();
strcpy(newname,name);
strcpy(hilfe,name);
strcat(hilfe,".vers");
len=strlen(name);
/* Jetzt Open() wieder auf DOS-Library umstellen */
SetFunction((struct Library*)DOSBase,-30,oldOpen);
/* um welche Extension handelt es sich ? */
for (x=0;x<anzahl && kenn==-1;x++)
{
if (!strnicmp(newname+(len-(*(info+x)).length),(*(info+x)).extension,
(*(info+x)).length))
{
pos=len-(*(info+x)).length;
kenn=x;
}
}
/* Neue Datei => Wenn keine Version angegeben, höchste lesen */
if (mode==MODE_NEWFILE && kenn!=-1)
{
if (p=stpchr(newname,'.'))
{
/* Versionsnummer vorhanden ? */
if (!(x=atoi(p+1)))
{
if (fh=Open(hilfe,MODE_OLDFILE))
{
FRead(fh,&x,sizeof(x),1);
Seek(fh,0,OFFSET_BEGINNING);
}
else
{
if (!(fh=Open(hilfe,MODE_NEWFILE)))
x=1000;
}
/* wenn Vers.-Nummer <1000 => Zusatzdatei 'updaten' */
if (x<999)
{
in=1;
x++;
FWrite(fh,&x,sizeof(x),1);
Close(fh);
}
else
return((BPTR)0);
}
}
}
/* wie bei MODE_NEWFILE, nur kein update auf Zusatzdatei */
else if (mode==MODE_OLDFILE && kenn!=-1)
{
if (p=stpchr(newname,'.'))
{
if (!(x=atoi(p+1)))
{
if (fh=Open(hilfe,MODE_OLDFILE))
{
in=1;
FRead(fh,&x,sizeof(x),1);
Close(fh);
}
}
}
}
/* Neue Dateinamen mit Versionsnamen erstellen */
if (x && kenn!=-1 && in)
{
sprintf(newname+pos,".%03d",x);
strcpy(newname+pos+4,(*(info+kenn)).extension);
}
fh=Open(newname,mode);
/* Datei öffnen, Vektor auf 'newopen' verbiegen, BPTR zurückgeben */
SetFunction((struct Library*)DOSBase,-30,newopen);
return(fh);
}
extern BPTR __asm newlock(register __d1 char *name,register __d2 long mode)
{
BPTR lock,fh;
char newname[256],hilfe[256],vname[256],*p;
short version;
/* Zugriff auf globale Daten, Libraryadressen etc. */
geta4();
strcpy(newname,name);
strcpy(vname,name);
/* Wenn keine Version angegeben, höchste lesen */
if (p=stpchr(newname,'.'))
{
/* Versionsnummer vorhanden ? */
if (!(version=atoi(p+1)))
{
strcpy(hilfe,p);
strcat(vname,".vers");
/* originale Open()-Funktion, dann Versuch Zusatzdatei mit
Versionsnummer zu lesen
*/
SetFunction((struct Library*)DOSBase,-30,oldOpen);
if (fh=Open(vname,MODE_OLDFILE))
{
FRead(fh,&version,sizeof(version),1);
Close(fh);
/* Versionsnummer in Dateiname einfügen */
sprintf(p,".%03d",version);
strcat(newname,hilfe);
}
SetFunction((struct Library*)DOSBase,-30,newopen);
}
}
/* Lock()-Funktion ausführen den Lock ermitteln, den Vektor wieder
verbiegen und den Lock zurückgeben
*/
SetFunction((struct Library*)DOSBase,-84,oldLock);
lock=Lock(newname,mode);
SetFunction((struct Library*)DOSBase,-84,newlock);
return(lock);
}